<?php


namespace App\Services\Business\Services;

use App\Services\Base\Interfaces\ConfigServiceInterface;
use App\Services\Business\Interfaces\VideoServiceInterface;
use App\Services\Member\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Log;
use function AlibabaCloud\Client\json;

class VideoService implements VideoServiceInterface
{


    public function store($data)
    {


        $video  =  aliyun_video_info($data['aliyun_video_id']);
        return   Video::create([
            'title' => $data['title'],
            'thumb' => $data['thumb'],
            'user_id' => $data['user_id'],
            'company_id' => $data['login_company_id'],
            'duration'=>$video['Duration']??0,
            'aliyun_video_id' => $data['aliyun_video_id'],
            'slug' => '',
            'course_id' => $data['course_id'],
            'chapter_id' => $data['chapter_id'],
            'category_id' => $data['category_id'],
            'my_category_id' => $data['my_category_id'],
            'created_at' => Carbon::now(),
            'updated_at' => Carbon::now()
        ]);

    }


    /**
     * @param int $id
     * @return array
     */
    public function find(int $id):array
    {

        return Video::query()
            ->with(['user:id,nick_name,avatar', 'shop','files', 'questions', 'tags:id,name', 'course', 'mappings', 'makers'])
            ->where('is_show', 1)
            ->findOrFail($id)->toArray();

    }


    /**
     * @param int $id
     * @return array
     */
    public function get(int $id):array
    {

        return Video::query()
            ->with(['user:id,nick_name,avatar', 'shop','files', 'questions', 'tags:id,name', 'course', 'mappings', 'makers'])
            ->where('is_show', 1)
            ->findOrFail($id)->toArray();

    }


    public function getUserVideos(int $userId, string $keyWords, int $page, int $size)
    {
        $query = Video::query()
            ->with(['category:id,name'])
            ->where('is_show', 1)
            ->when($userId, function ($query) use ($userId) {
                $query->where('user_id', $userId);
            })
            ->when($keyWords != '', function ($query) use ($keyWords) {
                $query->where('title', 'like', '%' . $keyWords . '%');
            })
            ->orderByDesc('created_at');

        $total = $query->count();
        $list = $query->forPage($page, $size)->get()->toArray();


        return compact('list', 'total');
    }


    /**
     * @param int $page
     * @param int $pageSize
     *
     * @return array
     */
    public function simplePage(int $page, int $pageSize): array
    {
        $query = Video::query()
            ->with(['course'])
            ->where('is_show', 1)
            ->orderByDesc('create_at');

        $total = $query->count();
        $list = $query->forPage($page, $pageSize)->get()->toArray();

        return compact('total', 'list');
    }


    /**
     * @param int $limit
     *
     * @return array
     */
    public function getLatestVideos(int $limit): array
    {
        return Video::query()
            ->with(['course'])
            ->where('is_show', 1)
            ->orderByDesc('created_at')
            ->limit($limit)
            ->get()
            ->toArray();
    }

    /**
     * @param array $ids
     *
     * @return array
     */
    public function getList(array $ids): array
    {
        $list = Video::query()
            ->select(['id','title','user_id','thumb','course_id'])
            ->whereIn('id', $ids)
            ->where('is_show', 1)
            ->orderBy('created_at')
            ->get()->toArray();

        return $list ?? [];
    }

    /**
     * @param array $courseIds
     * @return array
     */
    public function getCourseList(array $courseIds): array
    {
        return Video::query()
            ->where('is_show', 1)
            ->orderByDesc('created_at')
            ->whereIn('course_id', $courseIds)
            ->get()
            ->toArray();
    }

    /**
     * @param int $videoId
     * @param int $num
     */
    public function viewNumIncrement(int $videoId, int $num): void
    {
        Video::query()->where('id', $videoId)->increment('view_count', $num);
    }

    /**
     * @param string $fileId
     * @param string $service
     * @return array
     */


    public function deleteVideo(string $aliyunVideoId, ConfigServiceInterface $configService)
    {

        if ($aliyunVideoId) {
            aliyun_sdk_client();
            $config = $configService->getAliyunVodConfig();
            $option = [
                'VideoIds' => $aliyunVideoId,
            ];
            try {
                $result = \AlibabaCloud\Client\AlibabaCloud::rpc()
                    ->host($config['host'])
                    ->product('Vod')
                    ->version('2017-03-21')
                    ->action('DeleteVideo')
                    ->options([
                        'query' => $option
                    ])
                    ->request();
            } catch (\Exception $exception) {

                Log::info('删除视频' . $aliyunVideoId . '不存在');

            }
        }
    }

    public function deleteImage(string $mediaId, ConfigServiceInterface $configService)
    {

        if ($mediaId) {
            aliyun_sdk_client();
            $config = $configService->getAliyunVodConfig();
            $option = [
                'ImageIds' => $mediaId,
            ];
            try {
                $result = \AlibabaCloud\Client\AlibabaCloud::rpc()
                    ->host($config['host'])
                    ->product('Vod')
                    ->version('2017-03-21')
                    ->action('DeleteImage')
                    ->options([
                        'query' => $option
                    ])
                    ->request();
            } catch (\Exception $exception) {

                Log::info('删除图片' . $mediaId . '不存在');

            }
        }
    }



    //找到有同样标签的视频

    /**
     * @param $keywords
     * @param $video
     * @return array|Builder[]|Collection
     */
    public function findRecommendVideos($keywords, $video)
    {
        $videos = Video::query()
            ->with(['user'])
            ->whereHas('tags', function ($query) use ($video) {
                $query->whereIn('tag.id', array_column($video['tags'],'id'));
            })
            ->where('id', '<>', $video['id'])
            ->when($keywords, function ($query) use ($keywords) {
                $query->orWhere('title', 'like', '%' . $keywords . '%');
            })
            ->get();


        return $videos ?? [];
    }

    public function buildEncryptConfig(array $config)
    {

        try {

            aliyun_sdk_client();
            $result = \AlibabaCloud\Client\AlibabaCloud::rpc()
                ->host($config['host'])
                ->product('Kms')
                ->version('2017-03-21')
                ->options([
                    'KeyId' => $config['kms_key_id'],
                    'KeySpec' => 'AES_256',  // 根据需求选择密钥规格
                    // 可添加其他可选请求参数
                ])
                ->action('GenerateKMSDataKey')
                ->request();
            $encryptConfig = array();
            $encryptConfig["DecryptKeyUri"] = url_append_query('https://dev.zesow.com/api/v2/aliyun/decrypt', ['Ciphertext' => $result['CiphertextBlob']]);
            $encryptConfig["KeyServiceType"] = "KMS";
            $encryptConfig["CipherText"] = $result['CiphertextBlob'];
            $encryptConfig["KeyId"] = $result['KeyId'];
            return json_encode($encryptConfig);


        } catch (\Exception $exception) {

        }

    }

    /**
     * @param int $id
     * @return array
     */
    public function getVideoMappingIds(int $id): array
    {

        $video = Video::query()->with(['mapping_parents'])->where('id', $id)->firstOrFail();
        $ids = $this->getVideoParentIds($video->mapping_parents);
        return $ids;


    }

    /**
     * @param $videos
     * @return array
     */
    function getVideoParentIds($videos): array
    {
        $ids = [];
        foreach ($videos as $video) {
            $ids[] = $video->id;

            if ($video->mapping_parents) {
                $ids = array_merge($ids, $this->getVideoParentIds($video->mapping_parents));
            }
        }
        return $ids;
    }

    /**
     * @param $videoId
     * @return bool
     */
    public function hasRecommends($videoId): bool
    {
        return Recommend::query()->where('recommendable_id', $videoId)->where('recommendable_type', Video::class)->exists();
    }

    /**
     * @param $videoId
     * @return bool
     */
    public function hasProduct($videoId): bool
    {
        return Promotion::query()->where('promotionable_id', $videoId)->where('promotionable_type', Video::class)->exists();
    }

    public function getNoteUser($videoId)
    {

         return  Note::query()->where('video_id',$videoId)->pluck('user_id')->toArray();

    }


    public function  getVideoNoteFollowings($videoId,$userId)
    {
        $user  =User::find($userId);
        $followIds = $user->followings->isNotEmpty()?$user->followings->pluck('id')->toArray():[];
        //这里只查询有写笔记且是关注的人，不需要查全部
        $noteUserIds = Note::query()->where('video_id',$videoId)->where('user_id','<>',$userId)->pluck('user_id')->toArray();
        return array_intersect($followIds,$noteUserIds);

    }
    public function  getVideoIssueFollowings($videoId,$userId)
    {
        $user  =User::find($userId);
        $followIds = $user->followings->isNotEmpty()?$user->followings->pluck('id')->toArray():[];
        //这里只查询有写笔记且是关注的人，不需要查全部
        $noteUserIds = Issue::query()->where('video_id',$videoId)->where('user_id','<>',$userId)->pluck('user_id')->toArray();
        return array_intersect($followIds,$noteUserIds);

    }

    /**
     * @param int $userId
     * @return array
     */
    public function userLearningVideosPaginate(int $userId): array
    {
        return   UserVideoWatchRecord::query()
            ->with(['video'])
            ->where('user_id', $userId)
            ->orderByDesc('created_at')
            ->get()->toArray();

    }


}
